package com.cn.xiongmeng.czlxz.utils;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import com.cn.xiongmeng.czlxz.MainActivity;
import com.cn.xiongmeng.czlxz.activity.IndexActivity;
import com.cn.xiongmeng.czlxz.network.HttpClient;

import net.security.device.api.SecurityCode;
import net.security.device.api.SecurityDevice;
import net.security.device.api.SecurityToken;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

public class AliyunRiskUtils {
    private static final String TAG = "AliyunRiskUtils";
    public interface AliyunRiskCallback {
        // 200
        // 405 缓存中的设备状态为异常
        // 406 aliyun sdk获取token异常
        // 407 aliyun 认为设备异常
        // 408 请求“自有服务器”失败
        void onAliyunRisk(int code);
    }
    private interface GetTokenCallback {
        // 200 aliyu SDK成功获取token
        // 401 aliyu SDK获取token有错
        // 402 aliyu SDK获取token为null
        void onGetToken(int code, String token);
    }
    private interface SendTokenToSelfServerCallback {
        // 200 请求“自有服务器”成功，aliyu 认为设备正常
        // 403 请求“自有服务器”成功，aliyu 认为设备异常
        // 404 请求“自有服务器”失败
        void onSendTokenToSelfServer(int code);
    }
    public static void aliyunRisk(Context context, boolean oaidIsAgreed, AliyunRiskCallback callback){
        // 0、检查设备状态
        boolean deviceState = checkDeviceState(context);
        if (!deviceState){
            try {
                new Handler(Looper.getMainLooper()).post(() -> {
                    Toast.makeText(context, "设备异常！", Toast.LENGTH_LONG).show();
                });
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (callback != null) {
                callback.onAliyunRisk(405);
            }
            return;
        }
        // 1、确保一天只调用aliyun风控一次
        boolean aliyunRisk = checkAliyunRisk(context);
        if (aliyunRisk){
            if (callback != null) {
                callback.onAliyunRisk(200);
            }
            return;
        }
        // 2、信息采集
        try {
            informationExtract(context, oaidIsAgreed);
            Thread.sleep(2100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 3、获取aliyun token
        getToken(new GetTokenCallback(){
            @Override
            public void onGetToken(int code, String token) {
                if (code == 200){
                    // 4、将aliyun token送到“自有服务器”
                    sendTokenToSelfServer(context, token, new SendTokenToSelfServerCallback() {
                        @Override
                        public void onSendTokenToSelfServer(int code) {
                            if (code == 200){ // aliyun认为设备正常
                                try {
                                    DeviceStateChecker.setDeviceState(context, true);
                                    Thread.sleep(500);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                if (callback != null) {
                                    callback.onAliyunRisk(200);
                                }
                            } else if (code == 403) { // aliyun认为设备异常
                                // 将设备异常存入缓存
                                try {
                                    DeviceStateChecker.setDeviceState(context, false);
                                    // 提示用户
                                    new Handler(Looper.getMainLooper()).post(() -> {
                                        Toast.makeText(context, "设备异常！", Toast.LENGTH_LONG).show();
                                    });
                                    Thread.sleep(1000);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                if (callback != null) {
                                    callback.onAliyunRisk(407);
                                }
                            } else if (code == 404) { // 请求“自有服务器”失败
                                // 防止正常、异常设备，因请求失败，当天跳过阿里风控
                                SharedPreferences prefs = context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE);
                                SharedPreferences.Editor editor = prefs.edit();
                                editor.putLong("preSetDeviceState", 0);
                                editor.apply(); // apply异步，commit同步

                                try {
                                    new Handler(Looper.getMainLooper()).post(() -> {
                                        Toast.makeText(context, "服务器异常，请稍后再试", Toast.LENGTH_LONG).show();
                                    });
                                    Thread.sleep(1000);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                if (callback != null) {
                                    callback.onAliyunRisk(408);
                                }
                            }
                        }
                    });
                } else { // code 为401 402执行这段代码
                    // 防止正常、异常设备，因token失败，当天跳过阿里风控
                    SharedPreferences prefs = context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE);
                    SharedPreferences.Editor editor = prefs.edit();
                    editor.putLong("preSetDeviceState", 0);
                    editor.apply(); // apply异步，commit同步

                    try {
                        new Handler(Looper.getMainLooper()).post(() -> {
                            Toast.makeText(context, "token异常，请稍后再试", Toast.LENGTH_LONG).show();
                        });
                        Thread.sleep(1000); // 睡眠 2 秒
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (callback != null) {
                        callback.onAliyunRisk(406);
                    }
                }
            }
        });
    }
    // 返回设备状态，缓存没有的话，认为是true（测试完毕）
    private static boolean checkDeviceState(Context context){

        return DeviceStateChecker.checkDeviceState(context);
    }
    // 确保一天只调用aliyun风控一次
    private static boolean checkAliyunRisk(Context context){
        SharedPreferences prefs = context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE);

        long preSetDeviceState = prefs.getLong("preSetDeviceState", 0);
        long curDate = System.currentTimeMillis();
        long interval = (curDate - preSetDeviceState) / 1000;
        if (preSetDeviceState != 0 && interval < 24 * 60 * 60){
            return true;
        }
        return false;
    }
    // 信息采集（测试完毕）
    private static void informationExtract(Context context, boolean oaidIsAgreed){
        String ALIYUN_APPKEY = "shf68228bdhs168d70dedd58a0e4a093";
        //增加隐私数据采集开关，不采集NO_IDENTIFY_DEVICE_DATA类型数据，多选使用｜进行拼接。且"(NO_IDENTIFY_DEVICE_DATA))"处输入数据不可为空。
        Map<String, String> options = new HashMap<>();

        // 通过设备风险SDK采集信息，信息采集接口需要在风险场景中尽可能早的时候调用。
        // a、ctx：当前Application Context，或Activity Context。
        // b、appKey：用于标识用户身份，可在阿里云控制台的设备App管理申请获取。
        // c、options：信息采集可选项，默认可以为null。可选参数如下
        // d、securityInitListener：设备风险SDK信息采集回调接口，可在回调中判断信息采集是否成功。
        if (!oaidIsAgreed){
            options.put("DataType", "NO_UNIQUE_DEVICE_DATA");
        }
        SecurityDevice.getInstance().initWithOptions(context, ALIYUN_APPKEY, options, null);
    }
    // 调用阿里SDK获取token（测试完毕）
    private static void getToken(GetTokenCallback callback){
        SecurityToken st = SecurityDevice.getInstance().getDeviceToken();
        if(null != st){
            if(SecurityCode.SC_SUCCESS == st.code){
                Log.d("AliyunDevice", "token: " + st.token);
                // 发送token到业务自有服务器并查询阿里云设备风险识别接口。
                if (callback != null) {
                    callback.onGetToken(200, st.token);
                }
            } else {
                Log.e("AliyunDevice", "getDevicetoken error, code: " + st.code);
                if (callback != null) {
                    callback.onGetToken(401, "");
                }
            }
        } else {
            Log.e("AliyunDevice", "getDevicetoken is null.");
            if (callback != null) {
                callback.onGetToken(402, "");
            }
        }
    }
    // 将aliyun token送到“自有服务器”（测试完毕）
    private static void sendTokenToSelfServer(Context context, String token, SendTokenToSelfServerCallback callback){
        String jsonString = null;
        try {
            JSONObject jsonObject = new JSONObject();

            String key = "deviceToken";
            jsonObject.put(key, token);

            jsonString = jsonObject.toString();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        String url = "https://little-moon.fun/get_token_and_send_to_aliyun/";
        HttpClient httpClient = new HttpClient(context);

        httpClient.sendPostRequest(url, jsonString, new HttpClient.Callback() {
            @Override
            public void onFailure(Exception e) {
                Log.e(TAG, "Post 请求失败", e); // Log 错误信息
                if (callback != null) {
                    callback.onSendTokenToSelfServer(404);
                }
            }
            @Override
            public void onResponse(String response) {
                try {
                    // 提取从“自有服务器”传来的code的值
                    JSONObject jsonObject = new JSONObject(response);
                    int code = jsonObject.getInt("code");

                    if (code != 200){
                        if (callback != null) {
                            callback.onSendTokenToSelfServer(403);
                        }
                    } else {
                        if (callback != null) {
                            callback.onSendTokenToSelfServer(200);
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
